package org.walkerljl.commons.unit.powermock;//package org.walkerljl.practice.mock.powermock;

import org.walkerljl.commons.unit.dao.impl.UserDaoImpl;
import org.walkerljl.commons.unit.service.UserService;
import org.walkerljl.commons.unit.service.impl.UserServiceImpl;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.walkerljl.commons.unit.dao.UserDao;
import org.walkerljl.commons.unit.domain.User;


/**
 * @author lijunlin
 */
@RunWith(PowerMockRunner.class)
public class QuickStart {

    /**
     * Mock参数传递的对象
     */
    @Test
    public void testCallArgumentInstance() {
        User user = PowerMockito.mock(User.class);
        UserService userService = new UserServiceImpl();
        PowerMockito.when(user.getUserName()).thenReturn("mocked user name");
        Assert.assertTrue(userService.register(user));
    }

    /**
     * Mock方法内部New出来的对象
     *
     * <li>注解里写的类是需要mock的new对象代码所在的类</li>
     */
    @Test
    @PrepareForTest(UserDaoImpl.class)
    public void testCallInternalInstance() throws Exception {
        User user = new User("mocked userId", "mocked userName");
        UserDao userDao = new UserDaoImpl();
        PowerMockito.whenNew(User.class).withArguments("1").thenReturn(user);
        System.out.println(userDao.selectByUserId("1"));

        PowerMockito.whenNew(User.class).withArguments("1", "1").thenReturn(user);
        System.out.println(userDao.selectByUserIdAndName("1", "1"));
    }

    /**
     * Mock普通对象的final方法
     * <li>注解里写的类是需要mock的final方法所在的类</li>
     */
    @Test
    @PrepareForTest(User.class)
    public void testCallFinalMethod() {
        User user = PowerMockito.mock(User.class);
        UserService userService = new UserServiceImpl();
        PowerMockito.when(user.getGender()).thenReturn("mocked gender");
        Assert.assertTrue(userService.register(user));
    }

    /**
     * Mock静态方法
     */
    @Test
    @PrepareForTest(User.class)
    public void testCallStaticMethod() {
        User user = new User();
        PowerMockito.mockStatic(User.class);
        PowerMockito.when(User.doStatic()).thenReturn("mocked static");
        UserService userService = new UserServiceImpl();
        Assert.assertTrue(userService.register(user));
    }

    @Test
    @PrepareForTest(ClassUnderTest.class)
    public void testCallPrivateMethod() throws Exception {
        ClassUnderTest underTest = PowerMockito.mock(ClassUnderTest.class);
        PowerMockito.when(underTest.callPrivateMethod()).thenCallRealMethod();
        PowerMockito.when(underTest, "isExist").thenReturn(true);
        Assert.assertTrue(underTest.callPrivateMethod());
    }
}
